import mapboxgl, { Map, type BackgroundLayer } from 'mapbox-gl'
import type { Layer } from './types'

export interface SatelliteLayerOptions {
  id: string
  name: string
  url: string
  minZoom: number
  maxZoom: number
  visible?: boolean
  tileSize?: number
  overlayColor?: string
  overlayOpacity?: number
}

export default class SatelliteLayer implements Layer {
  public id: string
  public name: string
  private isVisible: boolean
  private map: mapboxgl.Map | undefined
  private url: string
  private minZoom: number
  private maxZoom: number
  private tileSize: number
  private overlayId: string | null
  private overlayColor: string
  private overlayOpacity: number

  public constructor(opts: SatelliteLayerOptions) {
    this.id = opts.id
    this.name = opts.name
    this.url = opts.url
    this.minZoom = opts.minZoom
    this.maxZoom = opts.maxZoom
    this.isVisible = opts.visible !== false
    this.tileSize = opts.tileSize || 256
    this.overlayId = opts.overlayColor ? `${opts.id}#overlay` : null
    ;(this.overlayColor = opts.overlayColor || '#000000'),
      (this.overlayOpacity = opts.overlayOpacity || 0.3)
  }

  // public constructor(visible: boolean) {
  //   this.isVisible = visible
  // }

  public get visible(): boolean {
    return this.isVisible
  }

  public set visible(ok: boolean) {
    if (ok === this.isVisible) {
      return
    }
    this.isVisible = ok
    if (this.map) {
      this.map.setLayoutProperty(this.id, 'visibility', this.isVisible ? 'visible' : 'none')
      if (this.overlayId) {
        this.map.setLayoutProperty(
          this.overlayId,
          'visibility',
          this.isVisible ? 'visible' : 'none'
        )
      }
    }
  }
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  public search(_lng: number, _lat: number, _r: number): any[] | null {
    return null
  }

  public attach(map: Map): void {
    this.map = map
    const layer: mapboxgl.RasterLayer = {
      id: this.id,
      type: 'raster',
      source: {
        type: 'raster',
        tiles: [
          this.url
          // 天地图
          // 'http://t0.tianditu.gov.cn/img_w/wmts?tk=1883a2da124fe27b3c281f9d65356e82&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles'
          // bing-satellite
          // "https://ecn.t3.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=0&dir=dir_n'"
        ],
        tileSize: this.tileSize
      },
      layout: {
        visibility: this.visible ? 'visible' : 'none'
      },
      minzoom: this.minZoom,
      maxzoom: this.maxZoom
      // maxzoom: 22
    }
    map.addLayer(layer)
    if (this.overlayId) {
      const overlayLayer: BackgroundLayer = {
        id: this.overlayId,
        type: 'background',
        layout: {
          visibility: this.visible ? 'visible' : 'none'
        },
        paint: {
          'background-color': this.overlayColor,
          'background-opacity': this.overlayOpacity
        },
        maxzoom: 14
      }
      map.addLayer(overlayLayer)
    }
  }
  public detach(): void {
    if (!this.map) {
      return
    }
    this.map.removeLayer(this.id)
    this.map.removeSource(this.id)
    if (this.overlayId) {
      this.map.removeLayer(this.overlayId)
    }
    this.map = undefined
  }
}

export function makeBingSatelliteLayer(visible: boolean = true) {
  return new SatelliteLayer({
    id: 'Satellite:Bing',
    name: '必应卫星影像',
    url: "https://ecn.t3.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=0&dir=dir_n'",
    tileSize: 256,
    minZoom: 0,
    maxZoom: 22,
    visible: visible,
    overlayColor: '#404f63',
    overlayOpacity: 0.4
  })
}

export function makeTiandituSatelliteLayer(visible: boolean = true) {
  return new SatelliteLayer({
    id: 'Satellite:Tianditu',
    name: '天地图卫星影像',
    url: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=1883a2da124fe27b3c281f9d65356e82&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles',
    tileSize: 256,
    minZoom: 0,
    maxZoom: 17,
    visible: visible,
    overlayColor: '#404f63',
    overlayOpacity: 0.6
  })
}
